import { createAlova } from 'alova';
import VueHook from 'alova/vue';
import adapterFetch from 'alova/fetch';
import { createAlovaMockAdapter } from '@alova/mock';
import { isString } from 'lodash-es';
import mocks from './mocks';
import { useUser } from '@/store/modules/user';
import { storage } from '@/utils/Storage';
import { useGlobSetting } from '@/hooks/setting';
import { PageEnum } from '@/enums/pageEnum';
import { isUrl } from '@/utils';
const { useMock, apiUrl, urlPrefix, loggerMock } = useGlobSetting();

// RESTful API 请求参数接口
interface RequestParams {
  path?: Record<string, string | number>;
  query?: Record<string, any>;
  data?: any;
  headers?: Record<string, string>;
}

const mockAdapter = createAlovaMockAdapter([...mocks], {
  // 全局控制是否启用mock接口，默认为true
  enable: useMock,

  // 非模拟请求适配器，用于未匹配mock接口时发送请求
  httpAdapter: adapterFetch(),

  // mock接口响应延迟，单位毫秒
  delay: 1000,

  // 自定义打印mock接口请求信息
  // mockRequestLogger: (res) => {
  //   loggerMock && console.log(`Mock Request ${res.url}`, res);
  // },
  mockRequestLogger: loggerMock,
  onMockError(error, currentMethod) {
    console.error('🚀 ~ onMockError ~ currentMethod:', currentMethod);
    console.error('🚀 ~ onMockError ~ error:', error);
  },
});

// 处理 URL 参数
const handleUrl = (url: string, params?: Record<string, string | number>): string => {
  if (!params) return url;
  return url.replace(/:([^/]+)/g, (_, key) => String(params[key] || ''));
};

// 创建基础 Alova 实例
export const Alova = createAlova({
  baseURL: apiUrl,
  statesHook: VueHook,
  // 关闭全局请求缓存
  // cacheFor: null,
  // 全局缓存配置
  // cacheFor: {
  //   POST: {
  //     mode: 'memory',
  //     expire: 60 * 10 * 1000
  //   },
  //   GET: {
  //     mode: 'memory',
  //     expire: 60 * 10 * 1000
  //   },
  //   HEAD: 60 * 10 * 1000 // 统一设置HEAD请求的缓存模式
  // },
  // 在开发环境开启缓存命中日志
  cacheLogger: process.env.NODE_ENV === 'development',
  requestAdapter: mockAdapter,
  beforeRequest(method) {
    const userStore = useUser();
    const token = userStore.getToken;

    if (!method.meta?.ignoreToken && token) {
      method.config.headers['Authorization'] = `Bearer ${token}`;
    }

    // 设置通用请求头
    method.config.headers = {
      'Content-Type': 'application/json',
      Accept: 'application/json',
      ...method.config.headers,
    };

    // 处理 URL
    const isUrlStr = isUrl(method.url as string);
    if (!isUrlStr && urlPrefix) {
      method.url = `${urlPrefix}${method.url}`;
    }
    if (!isUrlStr && apiUrl && isString(apiUrl)) {
      method.url = `${apiUrl}${method.url}`;
    }
  },
  responded: {
    onSuccess: async (response, method) => {
      // 如果需要原始响应，直接返回
      if (method.meta?.isReturnNativeResponse) {
        return response;
      }

      const status = response.status;

      // 处理不同的 HTTP 状态码
      if (status >= 200 && status < 300) {
        try {
          const data = await response.json();
          return data;
        } catch (e) {
          return response.body;
        }
      }

      // @ts-ignore
      const Message = window.$message;
      // @ts-ignore
      const Modal = window.$dialog;

      // 处理特定状态码
      switch (status) {
        case 401:
          // const m = modal.create({
          //   title: 'Dialog 预设',
          //   preset: 'dialog',
          //   content: '登录身份已失效，请重新登录!',
          // });
          Modal?.warning({
            title: '未授权',
            content: '登录身份已失效，请重新登录!',
            okText: '确定',
            closable: true,
            maskClosable: false,
            onOk: async () => {
              storage.clear();
              window.location.href = PageEnum.BASE_LOGIN;
            },
          });
          throw new Error('未授权访问');

        case 403:
          Message?.error('没有权限访问该资源');
          throw new Error('禁止访问');

        case 404:
          Message?.error('请求的资源不存在');
          throw new Error('资源不存在');

        case 500:
          Message?.error('服务器内部错误');
          throw new Error('服务器错误');

        default:
          if (status >= 400) {
            Message?.error(`请求失败 (${status})`);
            throw new Error('请求失败');
          }
      }
    },
    onError: (err: Error) => {
      // @ts-ignore
      window.$message?.error(err.message);
      return Promise.reject(err);
    },
  },
});

// RESTful API 请求方法
export const request = {
  get: <T = any>(url: string, { path, query, headers }: RequestParams = {}) => {
    const finalUrl = handleUrl(url, path);
    return Alova.Get<T>(finalUrl, {
      params: query,
      headers,
    });
  },

  post: <T = any>(url: string, { path, data, headers }: RequestParams = {}) => {
    const finalUrl = handleUrl(url, path);
    return Alova.Post<T>(finalUrl, data, {
      headers,
    });
  },

  put: <T = any>(url: string, { path, data, headers }: RequestParams = {}) => {
    const finalUrl = handleUrl(url, path);
    return Alova.Put<T>(finalUrl, data, {
      headers,
    });
  },

  delete: <T = any>(url: string, { path, headers }: RequestParams = {}) => {
    const finalUrl = handleUrl(url, path);
    return Alova.Delete<T>(finalUrl, {
      headers,
    });
  },

  patch: <T = any>(url: string, { path, data, headers }: RequestParams = {}) => {
    const finalUrl = handleUrl(url, path);
    return Alova.Patch<T>(finalUrl, data, {
      headers,
    });
  },
};

export default request;

// 项目，多个不同 api 地址，可导出多个实例
// export const AlovaTwo = createAlova({
//   baseURL: 'http://localhost:9001',
// });
